package client;

import java.util.ArrayList;

import communication.*;
import communication.message.Move;
import communication.message.Point;

/***
 * 
 * @author malasnickik
 * 
 */
public class PaperSoccerAI {

	private String nick;
	private ArrayList<Point> usedPoints;
	private ArrayList<Pair> usedLines;
	private Boolean up = null;
	private Point lastAdded;

	public PaperSoccerAI(String nick) {
		this.nick = nick;
		usedPoints = new ArrayList<Point>();
		lastAdded = new Point(0, 0);
		usedPoints.add(lastAdded);
		usedLines = new ArrayList<Pair>();
		AddAllBorderLinesAndPoints();
	}

	public Message GetAIResponse(Message receivedMessage) {

		Boolean myTurn = receivedMessage.getNextPlayer().getNick().equals(nick) ? true
				: false;
		if (up == null)
			up = receivedMessage.getNextPlayer().getNick().equals(nick) ? true
					: false;	
		try {

			ArrayList<Point> p = receivedMessage.getGameState().getPoints();
			for (int i = 0; i < p.size(); ++i) {
				if (usedPoints.contains(p.get(i)) == false)
					usedPoints.add(p.get(i));
			}
			if (p.size() > 0 &&myTurn==true) {
				Pair line = new Pair(lastAdded, p.get(0));
				usedLines.add(new Pair(lastAdded, p.get(0)));
				for (int i = 0; i + 1 < p.size(); ++i) {
					line = new Pair(p.get(i), p.get(i + 1));
					usedLines.add(line);
				}
				lastAdded = p.get(p.size() - 1);
			}
		} catch (NullPointerException e) {
			System.out.println("na poczatku nie ma punktow " + nick);
		}
		if (myTurn == false)
			return null;
		//else
		return GetResponseMessage(receivedMessage);
		

	}
	Message GetResponseMessage(Message receivedMessage)
	{
		Message m = new Message(MessageType.MOVE);
		Move mov = new Move();
		Point toAdd;
		for (toAdd=GetNextPoint(); usedPoints.contains(toAdd) == true && Math.abs(toAdd.getX())<=5; toAdd = GetNextPoint()) {
			if(usedPoints.contains(toAdd)==false)
				usedPoints.add(toAdd);
			usedLines.add(new Pair(lastAdded,toAdd));
			mov.addPoint(toAdd);
			System.out.println("x=" + toAdd.getX() + " y=" + toAdd.getY());
			lastAdded=toAdd;
		}
		usedLines.add(new Pair(lastAdded,toAdd));
		mov.addPoint(toAdd);
		lastAdded=toAdd;
		System.out.println("x=" + toAdd.getX() + " y=" + toAdd.getY());

		
		
		m.setMove(mov);
		m.setGameId(receivedMessage.getGameId());
		if(toAdd.getX()==4)
			System.out.println("x==4")	;
		return m;
		
	}

	Point GetNextPoint() {
		int go = (up == true) ? 1 : -1;
		Point to[] = new Point[8];
		to[0] = new Point(lastAdded.getX(), lastAdded.getY() + go);
		to[1] = new Point(lastAdded.getX() + 1, lastAdded.getY() + go);
		to[2] = new Point(lastAdded.getX() - 1, lastAdded.getY() + go);
		to[3] = new Point(lastAdded.getX() + 1, lastAdded.getY());
		to[4] = new Point(lastAdded.getX() - 1, lastAdded.getY());
		to[5] = new Point(lastAdded.getX() - 1, lastAdded.getY() - go);
		to[6] = new Point(lastAdded.getX() - 1, lastAdded.getY() - go);
		to[7] = new Point(lastAdded.getX(), lastAdded.getY() - go);
		for (int i = 0; i < to.length; ++i) {
			Pair line = new Pair(lastAdded, to[i]);
			if (LineUsed(line) == false)
				if (PointExistInBoard(to[i]) == true)
					return to[i];

		}

		// nie mam gdzie p�j��
		return to[0];
	}

	Boolean LineUsed(Pair toCheck) {
		for (int i = 0; i < usedLines.size(); ++i)
			if ((usedLines.get(i).point1.equals(toCheck.point1) && usedLines
					.get(i).point2.equals(toCheck.point2))
					|| (usedLines.get(i).point1.equals(toCheck.point2) && usedLines
							.get(i).point2.equals(toCheck.point1)))
				return true;

		return false;
	}

	Boolean PointExistInBoard(Point toCheck) {
		int x = toCheck.getX();
		int y = toCheck.getY();
		if (x > 4 || x < -4)
			return false;
		if (y > 6 || y < -6)
			return false;
		if (y == 6 || y == -6)
			if (x < -1 || x > 1)
				return false;
		return true;
	}

	void AddAllBorderLinesAndPoints()
	{
		ArrayList<Point> borderPoints=new ArrayList<Point>();
		for(int i=5;i>=-5;--i)
			borderPoints.add(new Point(4,i));
		borderPoints.add(new Point(3,-5));
		borderPoints.add(new Point(2,-5));
		borderPoints.add(new Point(1,-5));
		borderPoints.add(new Point(1,-6));
		borderPoints.add(new Point(0,-6));
		borderPoints.add(new Point(-1,-6));
		borderPoints.add(new Point(-1,-5));
		borderPoints.add(new Point(-2,-5));
		borderPoints.add(new Point(-3,-5));
		for(int i=-5;i<=5;++i)
			borderPoints.add(new Point(-4,i));
		borderPoints.add(new Point(-3,5));
		borderPoints.add(new Point(-2,5));
		borderPoints.add(new Point(-1,5));
		borderPoints.add(new Point(-1,6));
		borderPoints.add(new Point(0,6));
		borderPoints.add(new Point(1,6));
		borderPoints.add(new Point(1,5));
		borderPoints.add(new Point(2,5));
		borderPoints.add(new Point(3,5));
		
		usedPoints.addAll(borderPoints);
		
		for(int i=0;i+1<borderPoints.size();++i)
			usedLines.add(new Pair(borderPoints.get(i),borderPoints.get(i+1)));
		usedLines.add(new Pair(borderPoints.get(borderPoints.size()-1),borderPoints.get(0)));

		
			
	}

}
